// @File  : websocket.go
// @Author: JunLong.Liao&此处不应有BUG!
// @Date  : 2021/6/3
// @slogan: 又是不想写代码的一天，神兽保佑，代码无BUG！
//         ┏┓      ┏┓
//        ┏┛┻━━━━━━┛┻┓
//        ┃     ღ    ┃
//        ┃  ┳┛   ┗┳ ┃
//        ┃     ┻    ┃
//        ┗━┓      ┏━┛
//          ┃      ┗━━━┓
//          ┃ 神兽咆哮!  ┣┓
//          ┃         ┏┛
//          ┗┓┓┏━━━┳┓┏┛
//           ┃┫┫   ┃┫┫
//           ┗┻┛   ┗┻┛

package websoket2

import (
	"courseware/util"
	"courseware/util/rabbitmq_v2"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"log"
	"net/http"
	"sync/atomic"
)

func (manager *Manager) WsConnect(c *gin.Context) {
	upGrader := websocket.Upgrader{
		// cross origin domain
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
		// 处理 Sec-WebSocket-Protocol Header
		Subprotocols: []string{c.GetHeader("Sec-WebSocket-Protocol")},
	}

	conn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		util.ErrorResponse(c, "升级WebSocket失败", 1000)
		return
	}
	client := &Client{
		Id:      atomic.AddInt32(&WebSocketManager.incr, 1),
		Socket:  conn,
		Message: make(chan []byte, 1),
	}
	mq := rabbitmq_v2.NewMq(queueExchange)
	mq.MqConnect()
	go client.WriteRabbitMQ()
	go client.Read(manager)
	go client.Write()
	manager.RegisterClient(client)

}

var queueExchange = rabbitmq_v2.QueueExchange{
	"test_queue",
	"#.",
	"test",
	"topic",
	fmt.Sprintf("amqp://%s:%s@%s:%d/", "root", "123123", "127.0.0.1", 5672),
}

func (c *Client) WriteRabbitMQ() {
	for i := 0; i < 100; i++ {
		rabbitmq_v2.Send(queueExchange, fmt.Sprintf("{\"msg\":\"这是一条测试消息%v\"}", i))
	}
}

func (c *Client) Read(manager *Manager) {

	for {
		messageType, messageContent, err := c.Socket.ReadMessage()
		if err != nil {
			log.Printf("message:%s,messageType:%s,error:%e\n", messageContent, messageType, err)
			return
		}
		t := &TestPro{
			Socket: c.Socket,
		}
		rabbitmq_v2.Recv(queueExchange, t, 1)

		//
		// messageStruct := ReadMessageRequest{}
		// if err := json.Unmarshal(messageContent, &messageStruct); err != nil {
		// 	fmt.Printf("messageStruct:%s\n", messageStruct)
		// 	ResponseData, _ := json.Marshal(MessageResponse{Status: 201, Message: "消息内容不正确", Type: 1, FromId: systemId})
		// 	c.Message <- ResponseData
		// } else {
		// 	acceptClient, ok := manager.IdClientMap[messageStruct.AcceptId]
		// 	if !ok {
		// 		ResponseData, _ := json.Marshal(MessageResponse{Status: 201, Message: fmt.Sprintf("接收人：%v已离线或不存在", messageStruct.AcceptId), Type: 1, FromId: systemId})
		// 		c.Message <- ResponseData
		// 	} else {
		// 		ResponseData, _ := json.Marshal(MessageResponse{Status: 200, Message: messageStruct.Message, Type: 1, FromId: c.Id})
		// 		acceptClient.Message <- ResponseData
		// 	}
		// }
	}
}

type TestPro struct {
	msgContent string
	Socket     *websocket.Conn
}

// 实现发送者
func (t *TestPro) FailAction(dataByte []byte) error {
	fmt.Println(string(dataByte))
	return nil
}

// 实现接收者
func (t *TestPro) Consumer(dataByte []byte) error {
	t.Socket.WriteMessage(1, dataByte)
	return nil
}

func (c *Client) Write() {
	for {
		select {
		case message, ok := <-c.Message:
			fmt.Printf("write_message:%s\n", message)
			if !ok {
				fmt.Printf("err:%e\n", "消息接收失败")
			}
			err := c.Socket.WriteMessage(1, message)
			if err != nil {
				log.Printf("writeMessageError:%e\n", err)
			}
		}
	}
}

// 注册用户进程
func (manager *Manager) RegisterClient(c *Client) {
	manager.Register <- c
}

// 监听用户进程注册，用户进程注销
func (manager *Manager) Start() {
	for {
		select {
		case client := <-manager.Register:
			log.Printf("client [%s] connect", client.Id)
			/*      log.Printf("register client [%s] to group [%s]", client.Id, client.Group)
			 */
			manager.Lock.RLock()
			if _, ok := manager.IdClientMap[client.Id]; ok {
				manager.IdClientMap[client.Id].Socket.Close()
			}
			manager.IdClientMap[client.Id] = client
			ResponseData, _ := json.Marshal(MessageResponse{Status: 200, Message: fmt.Sprintf("连接成功，您的会话ID为[%v]", client.Id), Type: 1, FromId: systemId})
			client.Message <- ResponseData
			manager.Lock.RUnlock()

		// 注销
		case client := <-manager.UnRegister:
			manager.Lock.Lock()
			delete(manager.IdClientMap, client.Id)
			manager.Lock.Unlock()
			close(client.Message)
		}
	}
}
